home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / mpeg / mb_ordered.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  12KB  |  517 lines

  1. /*  
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code to implement an ordered dither. */
  22.  
  23. #include "video.h"
  24. #include "proto.h"
  25. #include "dither.h"
  26.  
  27. #define DITH_SIZE 16
  28.  
  29.  
  30. /* Structures used to implement macroblock ordered
  31.    dither algorithm.
  32. */
  33.  
  34. static unsigned char ***ditherPtr[DITH_SIZE];
  35.  
  36.  
  37. /*
  38.  *--------------------------------------------------------------
  39.  *
  40.  *  InitMBOrderedDither--
  41.  *
  42.  *    Structures intialized for ordered dithering. 
  43.  *
  44.  * Results:
  45.  *    None.
  46.  *
  47.  * Side effects:
  48.  *      None.
  49.  *
  50.  *--------------------------------------------------------------
  51.  */
  52.  
  53. void
  54. InitMBOrderedDither()
  55. {
  56.   unsigned char ****pos_2_cb;
  57.   unsigned char ***cb_2_cr;
  58.   unsigned char **cr_2_l;
  59.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  60.   int i, j, pos;
  61.   int err_range, threshval;
  62.  
  63.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  64.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  65.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  66.  
  67.   for (pos=0; pos<DITH_SIZE; pos++) {
  68.     
  69.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  70.  
  71.     for (j=0; j<CB_RANGE; j++) {
  72.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  73.     }
  74.  
  75.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  76.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  77.     }
  78.  
  79.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  80.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  81.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  82.  
  83.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  84.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  85.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  86.       }
  87.     }
  88.  
  89.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  90.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  91.     }
  92.  
  93.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  94.       
  95.       for (j=0; j<CR_RANGE; j++) {
  96.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  97.       }
  98.  
  99.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  100.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  101.       }
  102.  
  103.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  104.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  105.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  106.     
  107.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  108.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  109.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  110.     }
  111.       }
  112.       
  113.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  114.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  115.       }
  116.       
  117.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  118.     
  119.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  120.       (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
  121.                         (0*CR_RANGE*CB_RANGE)];
  122.     }
  123.  
  124.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  125.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  126.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  127.  
  128.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  129.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  130.           pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
  131.         else (cr_2_l[cr_rval])[l_val] =
  132.           pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
  133.       }
  134.     }
  135.  
  136.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  137.       (cr_2_l[cr_rval])[l_val] = 
  138.         pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
  139.     }
  140.       }
  141.     }
  142.   }
  143.  
  144.   for (i=0; i<DITH_SIZE; i++) {
  145.     ditherPtr[i] = pos_2_cb[i];
  146.   }
  147. }
  148.  
  149.  
  150.  
  151. /*
  152.  *--------------------------------------------------------------
  153.  *
  154.  * MBOrderedDitherImage --
  155.  *
  156.  *    Dithers an image using an ordered dither at macroblock level.
  157.  *    Assumptions made:
  158.  *      1) The color space is allocated y:cr:cb = 8:4:4
  159.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  160.  *      The channels are dithered based on the standard
  161.  *      ordered dither pattern for a 4x4 area. 
  162.  *
  163.  * Results:
  164.  *    None.
  165.  *
  166.  * Side effects:
  167.  *    None.
  168.  *
  169.  *--------------------------------------------------------------
  170.  */
  171. void
  172. MBOrderedDitherImage (lum, cr, cb, out, h, w)
  173.     unsigned char *lum;
  174.     unsigned char *cr;
  175.     unsigned char *cb;
  176.     unsigned char *out;
  177.     int h, w;
  178. {
  179.   unsigned char *l, *r, *b, *o1, *o2;
  180.   unsigned char *l2;
  181.   unsigned char L, R, B;
  182.   int i, j, mbaddr, mbwidth;
  183.   unsigned char ***dp0 = ditherPtr[0];
  184.   unsigned char ***dp2 = ditherPtr[2];
  185.   unsigned char ***dp4 = ditherPtr[4];
  186.   unsigned char ***dp6 = ditherPtr[6];
  187.   unsigned char ***dp8 = ditherPtr[8];
  188.   unsigned char ***dp10 = ditherPtr[10];
  189.   unsigned char ***dp12 = ditherPtr[12];
  190.   unsigned char ***dp14 = ditherPtr[14];
  191.   unsigned char ***dp1 = ditherPtr[1];
  192.   unsigned char ***dp3 = ditherPtr[3];
  193.   unsigned char ***dp5 = ditherPtr[5];
  194.   unsigned char ***dp7 = ditherPtr[7];
  195.   unsigned char ***dp9 = ditherPtr[9];
  196.   unsigned char ***dp11 = ditherPtr[11];
  197.   unsigned char ***dp13 = ditherPtr[13];
  198.   unsigned char ***dp15 = ditherPtr[15];
  199.  
  200.   l = lum;
  201.   l2 = lum + w;
  202.   r = cr;
  203.   b = cb;
  204.   o1 = out;
  205.   o2 = out+w;
  206.   mbwidth = w / 16;
  207.  
  208.   for (i=0; i<h; i+=4) {
  209.  
  210.     mbaddr = (i / 16) * mbwidth ;
  211.  
  212.     for (j=0; j<w; j+=8) {
  213.  
  214.       if (ditherFlags[mbaddr+(j/16)]) {
  215.     R = r[0]; B = b[0];
  216.     
  217.     L = l[0];
  218.     o1[0] = ((dp0[B])[R])[L];
  219.     L = l[1];
  220.     o1[1] = ((dp8[B])[R])[L];
  221.     L = l2[0];
  222.     o2[0] = ((dp12[B])[R])[L];
  223.     L = l2[1];
  224.     o2[1] = ((dp4[B])[R])[L];
  225.     
  226.     R = r[1]; B = b[1];
  227.     
  228.     L = l[2];
  229.     o1[2] = ((dp2[B])[R])[L];
  230.     L = l[3];
  231.     o1[3] = ((dp10[B])[R])[L];
  232.     L = l2[2];
  233.     o2[2] = ((dp14[B])[R])[L];
  234.     L = l2[3];
  235.     o2[3] = ((dp6[B])[R])[L];
  236.     
  237.     R = r[2]; B = b[2];
  238.     
  239.     L = l[4];
  240.     o1[4] = ((dp0[B])[R])[L];
  241.     L = l[5];
  242.     o1[5] = ((dp8[B])[R])[L];
  243.     L = l2[4];
  244.     o2[4] = ((dp12[B])[R])[L];
  245.     L = l2[5];
  246.     o2[5] = ((dp4[B])[R])[L];
  247.     
  248.     R = r[3]; B = b[3];
  249.     
  250.     L = l[6];
  251.     o1[6] = ((dp2[B])[R])[L];
  252.     L = l[7];
  253.     o1[7] = ((dp10[B])[R])[L];
  254.     L = l2[6];
  255.     o2[6] = ((dp14[B])[R])[L];
  256.     L = l2[7];
  257.     o2[7] = ((dp6[B])[R])[L];
  258.       }
  259.       
  260.       l += 8;
  261.       l2 += 8;
  262.       r += 4;
  263.       b += 4;
  264.       o1 += 8;
  265.       o2 += 8;
  266.     }
  267.     
  268.     l += w; l2 += w;
  269.     o1 += w; o2 += w;
  270.  
  271.     for (j=0; j<w; j+=8) {
  272.  
  273.       if (ditherFlags[mbaddr+(j/16)]) {
  274.  
  275.     R = r[0]; B = b[0];
  276.     
  277.     L = l[0];
  278.     o1[0] = ((dp3[B])[R])[L];
  279.     L = l[1];
  280.     o1[1] = ((dp11[B])[R])[L];
  281.     L = l2[0];
  282.     o2[0] = ((dp15[B])[R])[L];
  283.     L = l2[1];
  284.     o2[1] = ((dp7[B])[R])[L];
  285.     
  286.     R = r[1]; B = b[1];
  287.     
  288.     L = l[2];
  289.     o1[2] = ((dp1[B])[R])[L];
  290.     L = l[3];
  291.     o1[3] = ((dp9[B])[R])[L];
  292.     L = l2[2];
  293.     o2[2] = ((dp13[B])[R])[L];
  294.     L = l2[3];
  295.     o2[3] = ((dp5[B])[R])[L];
  296.     
  297.     R = r[2]; B = b[2];
  298.     
  299.     L = l[4];
  300.     o1[4] = ((dp3[B])[R])[L];
  301.     L = l[5];
  302.     o1[5] = ((dp11[B])[R])[L];
  303.     L = l2[4];
  304.     o2[4] = ((dp15[B])[R])[L];
  305.     L = l2[5];
  306.     o2[5] = ((dp7[B])[R])[L];
  307.     
  308.     R = r[3]; B = b[3];
  309.     
  310.     L = l[6];
  311.     o1[6] = ((dp1[B])[R])[L];
  312.     L = l[7];
  313.     o1[7] = ((dp9[B])[R])[L];
  314.     L = l2[6];
  315.     o2[6] = ((dp13[B])[R])[L];
  316.     L = l2[7];
  317.     o2[7] = ((dp5[B])[R])[L];
  318.       }
  319.  
  320.       l += 8;
  321.       l2 += 8;
  322.       r += 4;
  323.       b += 4;
  324.       o1 += 8;
  325.       o2 += 8;
  326.     }
  327.     
  328.     l += w; l2 += w;
  329.     o1 += w; o2 += w;
  330.   }
  331. }
  332.  
  333. void
  334. MBOrderedDitherDisplayCopy(vid_stream, mb_addr, motion_forw, r_right_forw,
  335.         r_down_forw, motion_back, r_right_back, r_down_back, past, future)
  336.     VidStream *vid_stream;
  337.     int mb_addr;
  338.     int motion_forw, r_right_forw, r_down_forw;
  339.     int motion_back, r_right_back, r_down_back;
  340.     unsigned char *past, *future;
  341. {
  342.   int right_back, right_forw, down_back, down_forw;
  343.   unsigned char *dest;
  344.   unsigned char *src1, *src2;
  345.   int row, col, row_size, rr;
  346.   int mc, mr;
  347.  
  348.   row = (mb_addr / vid_stream->mb_width) << 4;
  349.   col = (mb_addr % vid_stream->mb_width) << 4;
  350.   row_size = vid_stream->mb_width << 4;
  351.  
  352.   dest = vid_stream->current->display + (row * row_size) + col;
  353.  
  354.   if (motion_forw) {
  355.     right_forw = r_right_forw >> 1;
  356.     down_forw = r_down_forw >> 1;
  357.     src1 = past + ((row + down_forw) * row_size) + (col + right_forw);
  358.   }
  359.  
  360.   if (motion_back) {
  361.     right_back = r_right_back >> 1;
  362.     down_back = r_down_back >> 1;
  363.     src2 = future + ((row + down_back) * row_size) + (col + right_back);
  364.   }
  365.    
  366.   if (motion_forw) {
  367.     if (motion_back) {
  368.       for (rr = 0; rr<16; rr++) {
  369.     dest[0] = src1[0];    dest[1] = src2[1];
  370.     dest[2] = src1[2];    dest[3] = src2[3];
  371.     dest[4] = src1[4];    dest[5] = src2[5];
  372.     dest[6] = src1[6];    dest[7] = src2[7];
  373.     dest[8] = src1[8];    dest[9] = src2[9];
  374.     dest[10] = src1[10];    dest[11] = src2[11];
  375.     dest[12] = src1[12];    dest[13] = src2[13];
  376.     dest[14] = src1[14];    dest[15] = src2[15];
  377.  
  378.     dest += row_size;
  379.     src1 += row_size;
  380.     src2 += row_size;
  381.       }
  382.     }
  383.     else {
  384.       mc = col & 0x3;
  385.       mr = right_forw & 0x3;
  386.       if (!mc && !mr) {
  387.     /* Use 32 bit copy */
  388.     int *d, *s;
  389.  
  390.     d = (int *) dest;
  391.     s = (int *) src1;
  392.     row_size /= 4;
  393.     
  394.     for (rr = 0; rr < 16; rr++) {
  395.       d[0] = s[0];
  396.       d[1] = s[1];
  397.       d[2] = s[2];
  398.       d[3] = s[3]; 
  399.       d += row_size;
  400.       s += row_size;
  401.     }
  402.       } else if ((!mc || (mc == 2)) &&
  403.          (!mr || (mr == 2))) {
  404.     /* Use 16 bit copy */
  405.     short int *d, * s;
  406.     
  407.     d = (short int *) dest;
  408.     s = (short int *) src1;
  409.     row_size /= 2;
  410.     
  411.     for (rr = 0; rr < 16; rr++) {
  412.       d[0] = s[0];
  413.       d[1] = s[1];
  414.       d[2] = s[2];
  415.       d[3] = s[3]; 
  416.       d[4] = s[4];
  417.       d[5] = s[5];
  418.       d[6] = s[6];
  419.       d[7] = s[7]; 
  420.       d += row_size;
  421.       s += row_size;
  422.     }
  423.       }
  424.       else {
  425.     for (rr = 0; rr < 16; rr++) {
  426.       dest[0] = src1[0];
  427.       dest[1] = src1[1];
  428.       dest[2] = src1[2];
  429.       dest[3] = src1[3];
  430.       dest[4] = src1[4];
  431.       dest[5] = src1[5];
  432.       dest[6] = src1[6];
  433.       dest[7] = src1[7];
  434.       dest[8] = src1[8];
  435.       dest[9] = src1[9];
  436.       dest[10] = src1[10];
  437.       dest[11] = src1[11];
  438.       dest[12] = src1[12];
  439.       dest[13] = src1[13];
  440.       dest[14] = src1[14];
  441.       dest[15] = src1[15];
  442.       
  443.       dest += row_size;
  444.       src1 += row_size;
  445.     }
  446.       }
  447.     }
  448.   }
  449.   else if (motion_back) {
  450.     mc = col & 0x3;
  451.     mr = right_back & 0x3;
  452.     if (!mc && !mr) {
  453.       /* Use 32 bit copy */
  454.       int *d, *s;
  455.       
  456.       d = (int *) dest;
  457.       s = (int *) src2;
  458.       row_size /= 4;
  459.       
  460.       for (rr = 0; rr < 16; rr++) {
  461.     d[0] = s[0];
  462.     d[1] = s[1];
  463.     d[2] = s[2];
  464.     d[3] = s[3]; 
  465.     d += row_size;
  466.     s += row_size;
  467.       }
  468.     }
  469.     else if ((!mc || mc == 2) &&
  470.          (!mr || mr == 2)) {
  471.       /* Use 8 bit copy */
  472.       short int *d, *s;
  473.       
  474.       d = (short int *) dest;
  475.       s = (short int *) src2;
  476.       row_size /= 2;
  477.       
  478.       for (rr = 0; rr < 16; rr++) {
  479.     d[0] = s[0];
  480.     d[1] = s[1];
  481.     d[2] = s[2];
  482.     d[3] = s[3]; 
  483.     d[4] = s[4];
  484.     d[5] = s[5];
  485.     d[6] = s[6];
  486.     d[7] = s[7]; 
  487.     d += row_size;
  488.     s += row_size;
  489.       }
  490.     }
  491.     else {
  492.       for (rr = 0; rr < 16; rr++) {
  493.     /* Use 8 bit copy */
  494.     dest[0] = src2[0];
  495.     dest[1] = src2[1];
  496.     dest[2] = src2[2];
  497.     dest[3] = src2[3];
  498.     dest[4] = src2[4];
  499.     dest[5] = src2[5];
  500.     dest[6] = src2[6];
  501.     dest[7] = src2[7];
  502.     dest[8] = src2[8];
  503.     dest[9] = src2[9];
  504.     dest[10] = src2[10];
  505.     dest[11] = src2[11];
  506.     dest[12] = src2[12];
  507.     dest[13] = src2[13];
  508.     dest[14] = src2[14];
  509.     dest[15] = src2[15];
  510.     
  511.     dest += row_size;
  512.     src2 += row_size;
  513.       }
  514.     }
  515.   }
  516. }
  517.